package neteasy_music

import (
	"GraduationProject/public/models"
	"GraduationProject/worker/worker_tools"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"regexp"
	"strconv"
	"strings"
	"time"
)

var netEasyCookie = http.Cookie{
	Name:   "_ntes_nuid",
	Value:  "ff57c2c2391a39e121fc6db90f707bd7",
	Path:   "/",
	Domain: ".163.com",
	// 2039年10月3日星期一 下午8:49:12
	Expires: time.Date(2039, 10, 3, 8, 49, 12, 0, time.Local),
}

var (
	netEasyTick          = time.Tick(time.Second * 3)
	songIDRegex          = regexp.MustCompile(`https://music.163.com/weapi/v1/resource/comments/R_SO_4_([0-9]*)\?csrf_token=(.*)`)
	SongIDError          = errors.New("songID is not found")
	ParamsUnmarshalError = errors.New("params unmarshal error")
)

//func NetEasyMusicClient(songID string, limit, offset int64) ([]byte, error) {
func NetEasyMusicClient(urlStr string, ps string) (content []byte, nextPs string, err error) {
	//songID := "28196001"
	<-netEasyTick

	var p []models.Param
	if err := json.Unmarshal([]byte(ps), &p); err != nil {
		return nil, "", ParamsUnmarshalError
	}
	var (
		limit  string
		offset string
	)
	for _, v := range p {
		if v.Key == "limit" {
			limit = v.Value
		}
		if v.Key == "offset" {
			offset = v.Value
		}
	}

	find := songIDRegex.FindAllStringSubmatch(urlStr, 1)
	if len(find) < 1 {
		fmt.Println("not found songID: ", urlStr)
		return nil, "", SongIDError
	}

	songID := find[0][1]
	//csrf := ""
	csrf := find[0][2]

	//csrf := ""
	var req = struct {
		CsrfToken string `json:"csrf_token"` // "csrf_token":"",
		Limit     string `json:"limit"`      // "limit":"20",
		Offset    string `json:"offset"`     // "offset":"0",
		Rid       string `json:"rid"`        // "rid":"R_SO_4_" + song_id,
		Total     string `json:"total"`      // "total":"true"
	}{
		CsrfToken: csrf,
		Limit:     limit,
		Offset:    offset,
		Rid:       "R_SO_4_" + songID,
		Total:     "true",
	}
	bytes2, err := json.Marshal(req)
	if err != nil {
		return nil, "", err
	}
	param, key, err := EncParams(string(bytes2))
	if err != nil {
		return nil, "", err
	}

	//urlStr := "http://music.163.com/weapi/v1/resource/comments/R_SO_4_" + songID + "?csrf_token=" + csrf
	fmt.Println("url:", urlStr)
	params := url.Values{
		"params":    []string{param},
		"encSecKey": []string{key},
	}

	paramStr := params.Encode()
	fmt.Println("paramStr:", paramStr)

	request, err := http.NewRequest("POST", urlStr, strings.NewReader(paramStr))
	if err != nil {
		return nil, "", err
	}
	request.Header.Add("Host", "music.163.com")
	request.Header.Add("User-Agent", worker_tools.GetUserAgent())
	request.Header.Add("Content-Type", "application/x-www-form-urlencoded")

	request.AddCookie(&netEasyCookie)

	resp, err := http.DefaultClient.Do(request)
	if err != nil {
		return nil, ps, err
	}

	defer resp.Body.Close()
	all, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, ps, err
	}

	limitInt, _ := strconv.Atoi(limit)
	offsetInt, _ := strconv.Atoi(offset)
	nextOffsetInt := limitInt + offsetInt
	nextPsObj := []models.Param{
		{"limit", limit},
		{"offset", strconv.Itoa(nextOffsetInt)},
	}
	bytes, _ := json.Marshal(nextPsObj)

	return all, string(bytes), nil
}
